﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using RAP.Framework.Libary.DataSource;
using RAP.Framework.Libary.DataSource.Context;
using RAP.Framework.Libary.DataSource.Model;
using RAP.Framework.Libary.Utils;
using RAP.Web.Libary.Common.Model;
using System;
using System.Collections;

namespace RAP.Web.Libary.Controller.Attributes
{
	/// <summary>
	/// 返回非JSON格式的数据
	/// </summary>
	public class NotJSONResultAttribute : Attribute
	{
		private static IDictionary _notJSONResultActions = new Hashtable();

		/// <summary>
		/// 
		/// </summary>
		/// <param name="context"></param>
		public static void ProcessAttributes( ActionExecutedContext context )
		{
			var actionMethod = ( context.ActionDescriptor as ControllerActionDescriptor ).MethodInfo;
			var actionKey = $"{actionMethod.DeclaringType.FullName}.{actionMethod.Name}";
			var isNotJSONResultObj = _notJSONResultActions[ actionKey ];
			var controller = context.Controller as IWebController;
			if ( isNotJSONResultObj == null )
			{
				var attr = actionMethod.GetCustomAttributes<NotJSONResultAttribute>().FirstItem();
				if ( attr != null )
				{
					isNotJSONResultObj = true;
				}
				if ( isNotJSONResultObj == null )
				{
					attr = controller.GetType().GetCustomAttributes<NotJSONResultAttribute>().FirstItem();
					if ( attr != null )
					{
						isNotJSONResultObj = true;
					}
				}
			}
			var isNotJSONResul = isNotJSONResultObj != null ? isNotJSONResultObj.ToBooleanValue() : false;
			_notJSONResultActions[ actionKey ] = isNotJSONResul;
			if ( !isNotJSONResul )
			{
				//如果返回结果需要JSON，且当前返回结果不是JsonResult，则将结果数据用JsonResult包装一次再返回
				if ( !( context.Result is JsonResult ) && context.Result is ObjectResult )
				{
					var resultValue = ( context.Result as ObjectResult ).Value;
					if ( resultValue is ServiceError )
					{
						return;
					}
					else
					{
						if ( resultValue is IQueryResult )
						{
							var queryResult = resultValue as IQueryResult;
							if ( queryResult?.HasError != true )
							{
								resultValue = queryResult.Data;
							}
							else
							{
								resultValue = ServiceResult.CreateErrorResult( queryResult.Error.ErrorMessage, queryResult.Error.ErrorCode );
							}
						}
						//else if ( !( resultValue is ServiceResult ) )
						//{
						//	resultValue = ServiceResult.CreateSuccessResult( resultValue );
						//}
					}
					context.Result = controller.JSONContent( resultValue );
				}
			}
		}
	}
}
